package com.summer.jira.controller;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.jxls.common.Context;
import org.jxls.transform.poi.PoiTransformer;
import org.jxls.util.JxlsHelper;
import org.primefaces.model.UploadedFile;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Scope;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import com.summer.core.annotations.Logger;
import com.summer.core.annotations.ScopeType;
import com.summer.core.controller.LoginUserInfo;
import com.summer.core.util.FacesUtil;
import com.summer.core.util.IdGenerator;
import com.summer.jira.model.BugModuleSummary;
import com.summer.jira.model.BugSummary;
import com.summer.jira.model.BugSummaryFile;
import com.summer.jira.model.PersonBugSummary;
import com.summer.jira.model.PersonScoreSummary;
import com.summer.order.model.Cookbook;
import com.summer.user.model.User;

@Scope(ScopeType.VIEW)
@Component
public class BugSummaryHome {

	private UploadedFile file;

	@Logger
	static Log log;

	@Resource
	HibernateTemplate ht;
	@Resource
	LoginUserInfo loginUserInfo;

	private BugSummaryFile bugSummaryFile = new BugSummaryFile();
	
	private String module;

	public String export(List<BugSummary> list) {

		Map<String, BugModuleSummary> map = new HashMap<String, BugModuleSummary>();
		Map<String, PersonBugSummary> personMap = new HashMap<String, PersonBugSummary>();
		Map<String, PersonScoreSummary> personScoreMap = new HashMap<String, PersonScoreSummary>();
		Map<String, String> names = new HashMap<String, String>();
		List<BugModuleSummary> problemList = new ArrayList<BugModuleSummary>();
		List<PersonBugSummary> personList = new ArrayList<PersonBugSummary>();
		List<PersonScoreSummary> personScoreList = new ArrayList<PersonScoreSummary>();
		for (BugSummary p : list) {
			String module = p.getModule();
			String[] modules = module.split("eeeee");
			String personName = p.getAgent_user();
			BugModuleSummary o = null;
			PersonBugSummary person = null;
			PersonScoreSummary personScore = null;
			if (personMap.get(personName) != null) {
				person = personMap.get(personName);
			} else {
				person = new PersonBugSummary();
				person.setName(person().get(personName));
			}

			if (p.getProblem_level().toLowerCase().contains("urgent")) {
				person.setUrgent(person.getUrgent() == null ? 1 : person.getUrgent() + 1);
			}
			if (p.getProblem_level().toLowerCase().contains("very high")) {
				person.setVeryHigh(person.getVeryHigh() == null ? 1 : person.getVeryHigh() + 1);
			}
			if (p.getProblem_level().toLowerCase().contains("high")
					&& !p.getProblem_level().toLowerCase().contains("very high")) {
				person.setHigh(person.getHigh() == null ? 1 : person.getHigh() + 1);
			}
			if (p.getProblem_level().toLowerCase().contains("medium")) {
				person.setMedium(person.getMedium() == null ? 1 : person.getMedium() + 1);
			}
			if (p.getProblem_level().toLowerCase().contains("low")) {
				person.setLow(person.getLow() == null ? 1 : person.getLow() + 1);
			}
			if (p.getStatus().toLowerCase().equals("reopen")) {
				person.setReopen(person.getReopen() == null ? 1 : person.getReopen() + 1);
			}
			personMap.put(personName, person);
			if (personScoreMap.get(personName) != null) {
				personScore = personScoreMap.get(personName);
			} else {
				personScore = new PersonScoreSummary();
				personScore.setName(person().get(personName));
			}
			double high = person.getHigh() == null ? 0d : person.getHigh();
			double medium = person.getMedium() == null ? 0d : person.getMedium();
			double low = person.getLow() == null ? 0d : person.getLow();
			personScore.setScore((high * 2 + medium * 1 + low * 0.5d) / (high + medium + low));
			personScoreMap.put(personName, personScore);

			for (int i = 0; i < modules.length; i++) {
				String name = modules[i];
				if (map.get(name) != null) {
					o = map.get(name);
				} else {
					o = new BugModuleSummary();
					o.setName(name);
				}
				o.setTotal(o.getTotal() == null ? 1 : o.getTotal() + 1);
				if (p.getProblem_level().toLowerCase().contains("urgent")) {
					o.setUrgent(o.getUrgent() == null ? 1 : o.getUrgent() + 1);
				}
				if (p.getProblem_level().toLowerCase().contains("very high")) {
					o.setVeryHigh(o.getVeryHigh() == null ? 1 : o.getVeryHigh() + 1);
				}
				if (p.getProblem_level().toLowerCase().contains("high")
						&& !p.getProblem_level().toLowerCase().contains("very high")) {
					o.setHigh(o.getHigh() == null ? 1 : o.getHigh() + 1);
				}
				if (p.getProblem_level().toLowerCase().contains("medium")) {
					o.setMedium(o.getMedium() == null ? 1 : o.getMedium() + 1);
				}
				if (p.getProblem_level().toLowerCase().contains("low")) {
					o.setLow(o.getLow() == null ? 1 : o.getLow() + 1);
				}
				if (p.getDefect_from().equals("需求")) {
					o.setDemand(o.getDemand() == null ? 1 : o.getDemand() + 1);
				}
				if (p.getDefect_from().equals("设计")) {
					o.setDesign(o.getDesign() == null ? 1 : o.getDesign() + 1);
				}
				if (p.getDefect_from().equals("开发")) {
					o.setDevelop(o.getDevelop() == null ? 1 : o.getDevelop() + 1);
				}
				if (p.getDefect_from().equals("测试")) {
					o.setTest(o.getTest() == null ? 1 : o.getTest() + 1);
				}
				if (p.getDefect_from().equals("发布")) {
					o.setPublish(o.getPublish() == null ? 1 : o.getPublish() + 1);
				}
				if (p.getDefect_type().equals("界面")) {
					o.setUi(o.getUi() == null ? 1 : o.getUi() + 1);
				}
				if (p.getDefect_type().contains("功能")) {
					o.setFun(o.getFun() == null ? 1 : o.getFun() + 1);
				}
				if (p.getDefect_type().contains("性能")) {
					o.setPerform(o.getPerform() == null ? 1 : o.getPerform() + 1);
				}
				if (p.getTest_status().toLowerCase().contains("new")) {
					o.setNewDefects(o.getNewDefects() == null ? 1 : o.getNewDefects() + 1);
				}
				if (p.getTest_status().toLowerCase().contains("second")) {
					o.setSecondDefects(o.getSecondDefects() == null ? 1 : o.getSecondDefects() + 1);
				}
				if (p.getTest_status().toLowerCase().contains("reappear")) {
					o.setReappear(o.getReappear() == null ? 1 : o.getReappear() + 1);
				}
				map.put(name, o);
			}
		}
		for (String s : map.keySet()) {
			problemList.add(map.get(s));
		}
		StringBuffer sb = new StringBuffer();
		for (String s : personMap.keySet()) {
			personList.add(personMap.get(s));
			if(personMap.get(s).getName() == null) {
				continue;
			}
			sb.append(personMap.get(s).getName()).append("、");
		}
		for (String s : personScoreMap.keySet()) {
			personScoreList.add(personScoreMap.get(s));
		}

		bugSummaryFile.setTotalCount(list.size());
		bugSummaryFile.setDevelop(sb.toString().substring(0, sb.length()-1));
		bugSummaryFile.setDevelopCount(personList.size());
		String[] modules = module.replace("，", ",").split(",");
		List<Map<String, Object>> testArea = new ArrayList<Map<String, Object>>();
		for (int i = 0; i < modules.length; i++) {
			Map<String, Object> m = new HashMap<String, Object>();
			m.put("index", i+1);
			m.put("module", modules[i]);
			testArea.add(m);
		}
//		List<String> testArea =  Arrays.asList(modules);
		bugSummaryFile.setTestArea(testArea);

		HttpServletRequest request = FacesUtil.getHttpServletRequest();

		String fileName = IdGenerator.randomUUID() + ".xlsx";
		String xlsPath = request.getSession().getServletContext().getRealPath("/") + "template/bugSummaryTemplate.xlsx";
		String ctxPath = request.getSession().getServletContext().getRealPath("/") + "temp";
		File dir = new File(ctxPath);
		if (!dir.exists()) {
			dir.mkdir();
		}
		File file = new File(dir, fileName);
		try {
			try {
				InputStream is = new FileInputStream(xlsPath); // 输入流
				OutputStream os = new FileOutputStream(file);// 输出流
				Context context = new Context();
				context.putVar("problemList", problemList);
				context.putVar("personList", personList);
				context.putVar("personScoreList", personScoreList);
				context.putVar("file", bugSummaryFile);
				JxlsHelper jh = JxlsHelper.getInstance();
				jh.processTemplate(is, os, context);

				
				String newFileName = IdGenerator.randomUUID() + ".xlsx";
				if (!StringUtils.isEmpty(bugSummaryFile.getFileName())) {
					newFileName = bugSummaryFile.getFileName() + ".xlsx";
				}
				is = new FileInputStream(ctxPath+"/"+fileName);// 输入流
                os = new FileOutputStream(ctxPath+"/"+newFileName);// 输出流
                PoiTransformer transformerww=PoiTransformer.createTransformer(is, os);
                Workbook workbook =transformerww.getWorkbook();
                Sheet sheet=workbook.getSheetAt(3);
                if(personList.size() > 0) {
                	sheet.addMergedRegion(new CellRangeAddress(5,5+personList.size() -1 ,6,7));
                }
                transformerww.write();
                os.close();
                fileName = newFileName;
                file.delete();
				// 载入模板、处理导出
//				AreaBuilder areaBuilder = new XlsCommentAreaBuilder(trans);
//				List<Area> areaList = areaBuilder.build();
//				areaList.get(1).applyAt(new CellRef("A1"), context);
//				os.flush();
//				os.close();
//				is.close();
			} catch (Exception ex) {
				System.out.println(ex.getMessage());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return fileName;
	}

	@Transactional(readOnly = false, rollbackFor = Exception.class)
	public void importExcel() {
		if (file == null || file.getContents().length == 0) {
			FacesUtil.addErrorMessage("未发现上传的文件！");
			return;
		}
		InputStream is;
		try {

			is = file.getInputstream(); // 文件流
			Workbook wbs = WorkbookFactory.create(is);
			Sheet sheet = wbs.getSheetAt(0);
			int rowCount = sheet.getPhysicalNumberOfRows(); // 获取总行数
			List<BugSummary> list = new ArrayList<BugSummary>();
			// 遍历每一行
			for (int r = 1; r < rowCount; r++) {
				log.info("开始整第" + r + "条记录");
				XSSFRow row = (XSSFRow) sheet.getRow(r);
				/** 总列数 */
				int cellCount = sheet.getRow(0).getPhysicalNumberOfCells(); // 获取总列数
				// 遍历每一列
				BugSummary o = null;
				if (r > 0) {
					o = new BugSummary();
					o.setId(IdGenerator.randomUUID());
				}
				for (int c = 0; c < cellCount; c++) {
					Cell cell = row.getCell(c);

					if (cell == null) {
						continue;
					}
					String columnName = sheet.getRow(0).getCell(c).getStringCellValue();
					cell.setCellType(1);
					/** 单元格 */
					Object cellValue = getValue(cell);
					if (o != null) {
						int index = c;
						setValues(o, columnName, cellValue);
					}
				}
				if (o != null) {
//					o.setUploader(loginUserInfo.getLoginUser());
//					o.setUpload_time(new Date());
					list.add(o);
					log.info("第" + r + "条数据为：" + o);
				}
			}
//			if(list != null && list.size() > 0) {
//				ht.saveOrUpdateAll(list);
//			}
			String fileName = export(list);
			try {
				download(fileName);
			} catch (Exception e) {
				e.printStackTrace();
			}
			FacesUtil.addInfoMessage("记录生成成功，请检查下载结果");
		} catch (Exception e) {
			e.printStackTrace();
			FacesUtil.addErrorMessage("批量导入失败！请检查上传结果！");
		}
	}

	public void download(String fileName) {
		InputStream in = null; // 获取文件的流
		OutputStream out = null; // 对浏览器的输出流
		try {
			String filename = fileName;// 设置保存文件名称及格式
			FacesUtil.getHttpServletResponse().setContentType("multipart/form-data");
			FacesUtil.getHttpServletResponse().setHeader("Content-Disposition",
					"attachment;filename=" + new String(filename.getBytes("utf-8"), "ISO8859-1"));
			String ctxPath = FacesUtil.getHttpServletRequest().getSession().getServletContext().getRealPath("/")
					+ "/temp";
			InputStream fis = new BufferedInputStream(new FileInputStream(ctxPath + "/" + fileName));
			byte[] b = new byte[fis.available()];
			fis.read(b);
			fis.close();
			/* 数据流写入数据 */
			in = new ByteArrayInputStream(b);
			out = FacesUtil.getHttpServletResponse().getOutputStream();
			byte[] by = new byte[1024];
			int len = 0;
			while ((len = in.read(by)) > 0) {
				out.write(by, 0, len);
			}
			File tempFile = new File(ctxPath + "/" + fileName);
			if (tempFile != null) {
				tempFile.delete();
			}
			FacesUtil.getCurrentInstance().responseComplete();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {

		}
	}

	private Object getValue(Cell cell) {
		int cellType = cell.getCellType();
		Object cellValue = null;
		switch (cellType) {
		case Cell.CELL_TYPE_STRING: // 文本
			cellValue = cell.getStringCellValue();
			break;
		case Cell.CELL_TYPE_NUMERIC: // 数字、日期
			if (DateUtil.isCellDateFormatted(cell)) {
				cellValue = cell.getDateCellValue(); // 日期型
			} else {
				cellValue = String.valueOf(cell.getNumericCellValue()); // 数字
			}
			break;
		case Cell.CELL_TYPE_BOOLEAN: // 布尔型
			cellValue = String.valueOf(cell.getBooleanCellValue());
			break;
		case Cell.CELL_TYPE_BLANK: // 空白
			cellValue = cell.getStringCellValue();
			break;
		case Cell.CELL_TYPE_ERROR: // 错误
			cellValue = "错误";
			break;
		case Cell.CELL_TYPE_FORMULA: // 公式
			cellValue = "错误";
			break;
		default:
			cellValue = "错误";
		}
		return cellValue;
	}

	public void setValues(BugSummary o, String columnName, Object value) {
		try {
			String prop = methodName().get(columnName);
			String setMethod = "set" + prop.substring(0, 1).toUpperCase() + prop.substring(1);
			String getMethod = "get" + prop.substring(0, 1).toUpperCase() + prop.substring(1);
			Object res = o.getClass().getMethod(getMethod).invoke(o);
			if (res != null) {
				value = res + "eeeee" + value;
			}
			Object val = value;
			Class clazz = String.class;
			if (prop.equals("vote") || prop.equals("reopen_times")) {
				clazz = Integer.class;
				String regEx = "[^0-9]";
				Pattern p = Pattern.compile(regEx);
				Matcher m = p.matcher(val.toString());
				val = Integer.parseInt(m.replaceAll("").trim());
			}
			if (prop.contains("time") && !prop.contains("times")) {
				clazz = Date.class;
				String[] a = value.toString().split(" ");
				String[] d = a[0].split("/");
				String str = "20" + d[2] + numberMap().get(d[1].replace("月", "")) + d[0] + " " + a[2] + " " + a[1];
				val = new SimpleDateFormat("yyyyMMdd a hh:mm").parse(str);
			}
			o.getClass().getMethod(setMethod, new Class[] { clazz }).invoke(o, new Object[] { val });
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private Map<String, String> methodName() {
		Map<String, String> map = new HashMap<String, String>();
		map.put("Custom field (问题单等级)", "problem_level");
		map.put("主题", "theme");
		map.put("Custom field (测试状态)", "test_status");
		map.put("状态", "status");
		map.put("模块", "module");
		map.put("Custom field (缺陷分类)", "defect_type");
		map.put("报告人", "reporter");
		map.put("Custom field (问题责任人)", "res_user");
		map.put("经办人", "agent_user");
		map.put("Custom field (Fixed日期)", "fix_time");
		map.put("创建", "create_time");
		map.put("Custom field (缺陷来源)", "defect_from");
		map.put("问题类型", "problem_type");

		map.put("Issue key", "issue_key");
		map.put("Issue id", "issue_id");
		map.put("Project key", "project_key");
		map.put("Project name", "project_name");
		map.put("Project type", "project_type");
		map.put("Project lead", "project_lead");
		map.put("Project description", "project_description");
		map.put("Project url", "project_url");
		map.put("解决结果", "solve_result");
		map.put("创建人", "creator");
		map.put("更新", "update_time");
		map.put("最近查看的", "recently_see_time");
		map.put("解决", "solve_time");
		map.put("影响版本", "affect_version");
		map.put("到期日", "deadline");
		map.put("投票", "vote");
		map.put("标签", "mark");
		map.put("描述", "description");
		map.put("环境", "environment");
		map.put("关注人", "watcher");
		map.put("原预估时间", "pre_expect_time");
		map.put("剩余时间", "surplus_time");
		map.put("耗费时间", "used_time");
		map.put("工作比率", "work_ratio");
		map.put("Σ 原预估时间", "sum_pre_expect_time");
		map.put("Σ 预估剩余时间", "sum_pre_surplus_time");
		map.put("Σ 耗费时间", "sum_used_time");
		map.put("安全级别", "safe_level");
		map.put("Outward issue link (Relates)", "outward_issue_link");
		map.put("附件", "files");
		map.put("Custom field (Epic Colour)", "epic_colour");
		map.put("Custom field (Epic Link)", "epic_link");
		map.put("Custom field (Epic Name)", "epic_name");
		map.put("Custom field (Epic Status)", "epic_status");
		map.put("Custom field (Rank)", "rank");
		map.put("Custom field (Reopen日期)", "reopen_time");
		map.put("Custom field (Reopen次数)", "reopen_times");
		map.put("Custom field (Story Points)", "story_points");
		map.put("Custom field (严重级别)", "serious_level");
		map.put("Custom field (任务来源)", "task_from");
		map.put("Custom field (优先级)", "priority");
		map.put("Custom field (关闭日期)", "close_time");
		map.put("Custom field (历史问题)", "history_problem");
		map.put("Custom field (框架问题)", "frame_problem");
		map.put("Custom field (测试时间)", "test_time");
		map.put("Custom field (测试版本)", "test_version");
		map.put("Custom field (缺陷重现概率)", "defect_reproduce_chance");
		map.put("Custom field (解决方案)", "sovle_method");
		map.put("Custom field (重新打开次数)", "reopen_times_cn");
		map.put("Custom field (问题原因)", "problem_reason");
		map.put("Custom field (问题类型)", "problem_type_custom");
		map.put("Custom field (项目阶段)", "project_phase");
		map.put("Custom field (预估工时)", "expect_hours");
		map.put("备注", "remark");
		return map;
	}

	private Map<String, String> numberMap() {
		Map<String, String> map = new HashMap<String, String>();
		map.put("一", "01");
		map.put("二", "02");
		map.put("三", "03");
		map.put("四", "04");
		map.put("五", "05");
		map.put("六", "06");
		map.put("七", "07");
		map.put("八", "08");
		map.put("九", "09");
		map.put("十", "10");
		map.put("十一", "11");
		map.put("十二", "12");
		return map;
	}

	public UploadedFile getFile() {
		return file;
	}

	public void setFile(UploadedFile file) {
		this.file = file;
	}

	private static Map<String, String> getMethodName1() {
		Map<String, String> map = new HashMap<String, String>();
		map.put("Custom field (问题单等级)", "problem_level");
		map.put("主题", "theme");
		map.put("Custom field (测试状态)", "test_status");
		map.put("状态", "status");
		map.put("模块", "module");
		map.put("Custom field (缺陷分类)", "defect_type");
		map.put("报告人", "reporter");
		map.put("Custom field (问题责任人)", "res_user");
		map.put("经办人", "agent_user");
		map.put("Custom field (Fixed日期)", "fix_time");
		map.put("创建", "create_time");
		map.put("Custom field (缺陷来源)", "defect_from");
		map.put("问题类型", "problem_type");
		return map;
	}

	private static Map<String, String> numberMap1() {
		Map<String, String> map = new HashMap<String, String>();
		map.put("一", "01");
		map.put("二", "02");
		map.put("三", "03");
		map.put("四", "04");
		map.put("五", "05");
		map.put("六", "06");
		map.put("七", "07");
		map.put("八", "08");
		map.put("九", "09");
		map.put("十", "10");
		map.put("十一", "11");
		map.put("十二", "12");
		return map;
	}

	private Map<String, String> person() {
		Map<String, String> person = new HashMap<String, String>();
		person.put("wangl", "王蕾");
		person.put("mouqiang", "牟强");
		person.put("xiapy", "夏平野");
		person.put("zhangss", "张思思");
		person.put("hexd", "何晓丹");
		person.put("caogzh", "曹广舟");
		person.put("zhangly", "张励源");
		person.put("songjia", "宋佳");
		person.put("liulj", "刘立佳");
		person.put("Liuzhw", "刘振伟");
		person.put("lixiul", "李秀亮");
		person.put("yangguang", "杨光");
		person.put("wangchenglong", "王成龙");
		person.put("guojh", "郭佳赫");
		person.put("hugy", "胡高月");
		person.put("liuf", "刘方");
		person.put("liqn", "李秋娜");
		return person;
	}

	public BugSummaryFile getBugSummaryFile() {
		return bugSummaryFile;
	}

	public void setBugSummaryFile(BugSummaryFile bugSummaryFile) {
		this.bugSummaryFile = bugSummaryFile;
	}

	public String getModule() {
		return module;
	}

	public void setModule(String module) {
		this.module = module;
	}
	public static void main(String[] args) {
//		String a = "456465eeeee45649879eeeeeeqwerda4eeeeesf54x4aseeeee56dfsd55xc1eeeeev32zxeeeee1cv4adsfasd";
//		String[] res = a.split("eeeee");
//		for (int i = 0; i < res.length; i++) {
//			
//					System.out.println(res[i]);
//		}
		User user = new User();
		user.setId("abc");
		Cookbook c = new Cookbook();
		BeanUtils.copyProperties(user	, c);
		System.out.println(c.getId());
	}
	

}
